package p.ithorns.example.statemachine.test;

import p.ithorns.example.statemachine.core.State;
import p.ithorns.example.statemachine.core.StateEnum;
import p.ithorns.example.statemachine.core.StateMachine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * FlowStateMachine
 * 流程状态机
 *
 * @author ithorns
 * @version 1.0.0
 * @date 2022/11/13 12:22
 */
@Slf4j
@Component
public class FlowStateMachine extends StateMachine {

    @Override
    public Map<StateEnum, State> declareStates() {
        Map<StateEnum, State> states = new HashMap<>(8);

        FlowState created = new FlowState(FlowStatus.CREATED);
        FlowState approving = new FlowState(FlowStatus.APPROVING);
        FlowState receiving = new FlowState(FlowStatus.RECEIVING);
        FlowState received = new FlowState(FlowStatus.RECEIVED);
        FlowState assigned = new FlowState(FlowStatus.ASSIGNED);
        FlowState completed = new FlowState(FlowStatus.COMPLETED);
        FlowState evaluated = new FlowState(FlowStatus.EVALUATED);

        // 创建 -> 待审批
        created.addAction(new CreateAction(created, approving));
        // 待审批 -> 待接收
        approving.addAction(new ApproveAction(approving, receiving));
        // 待审批 -> 完结
        approving.addAction(new CompleteAction(approving, completed));
        // 待接收 -> 已接收
        receiving.addAction(new ReceiveAction(receiving, received));
        // 已接收 -> 已指派
        received.addAction(new AssignAction(received, assigned));
        // 已指派 -> 完结
        assigned.addAction(new CompleteAction(received, completed));
        // 完结 -> 评价
        completed.addAction(new EvaluateAction(completed, evaluated));

        states.put(FlowStatus.CREATED, created);
        states.put(FlowStatus.APPROVING, approving);
        states.put(FlowStatus.RECEIVING, receiving);
        states.put(FlowStatus.RECEIVED, received);
        states.put(FlowStatus.ASSIGNED, assigned);
        states.put(FlowStatus.COMPLETED, approving);
        states.put(FlowStatus.EVALUATED, evaluated);

        return states;
    }

}